Data Management Report Transformative Change Assessment Corpus - SOD

Author
Affiliation

Rainer M. Krug

Published

April 9, 2024

Doi
Abstract

The literature search for the assessment corpus was conducted using search terms provided by the experts and refined in co-operation with the Knowldge and Data task force. The search was conducted using OpenAlex, scripted from R to use the API. Search terms for the following searches were defined: Transformative Change, Nature / Environment and additional search terms for individual chapters and sub-chapters To assess the quality of the corpus, sets of key-papers were selected by the experts to verify if these are in the corpus. These key-papers were selected per chapter / sub-chapter to ensure that the corpus is representative of each chapter.

Keywords

DMR, TCA, Assessment Corpus

DOI GitHub release GitHub commits since latest release License: CC BY 4.0

Working Title

IPBES_TCA_Corpus

Code repo

Github repository

Build No: 413

Introduction

The following terminology is used in this document:

  • Individual corpus: The corpus resulting from one search term, e.g. transformative or nature or ChX_Y
  • Assessment Corpus: The corpus resulting from the search terms transformative AND nature
  • Chapter corpus: The corpus resulting from transformative AND Nature AND ChX_Y

The following searches are conducted on Title and Abstrat only as the availability of fulltext drops in 2020. OpenAlex did “inherit” fro Microsoft Academic their initial corpus in 2021 which contained a lot of fulltext for searches. After that time, other sources had to be used which did not include fulltext for searches. To eliminate this bias, we linit the search for terms in abstract and title only.

Search Terms

Here are the search terms used in this document. They were provided by the authors, and some adaptations were done by the tsu to adopt them for OpenAlex.

Transformative Change

Show the code
cat(params$s_1_transformative_change)
(
    (
        (
            transformation
            OR transition
            OR transformative
            OR "transformative change"
        )
        OR (
            (
                shift
                OR change
            )
            AND (
                fundamental
                OR deep
                OR radical
            )
        )
    )
    AND (
        socio
        OR social
        OR politics
        OR political
        OR governance
        OR economic
        OR cultural
        OR system
        OR technological
        OR inner
        OR personal
        OR financial
        OR business
    )
)
OR (
    (
        "transformative change"
        OR "deliberate transformation*"
        OR "transformative turn"
        OR transition
        OR "social-ecological change*"
        OR "deep change"
        OR "fundamental alteration"
        OR "profound change"
        OR "profound transformation"
        OR "radical transformation"
        OR "transformational change"
        OR "complete change"
        OR "complete transformation"
        OR "drastic change"
        OR "in-depth transformation"
        OR "progressive change"
        OR "radical alteration"
        OR "radical change"
        OR "revolutionary change"
        OR "significant modification"
        OR "total transformation"
        OR transition
        OR pathway
        OR power
        OR agency
        OR scale
        OR leverage
        OR context
        OR process
        OR regime
        OR shift
        OR views
        OR value
        OR structure
        OR institution
        OR deliberate
        OR structural
        OR fundamental
        OR system
        OR deep
        OR radical
        OR profound
        OR drastic
        OR widespread
        OR political
        OR economical
        OR structur
        OR complete
        OR progressive
        OR revolutionary
        OR substantial
        OR significant
    )
    AND (
        transformation
        OR alteration
        OR change
        OR turn
        OR action
        OR transition
        OR shift
    )
)

Nature

Show the code
#|

cat(params$s_1_nature_environment)
biodiversity
OR marine
OR terrestrial
OR forest*
OR woodland*
OR grassland*
OR savanna*
OR shrubland*
OR peatland
OR ecosystem
OR lake
OR river
OR sea
OR ocean
OR meadow
OR heathland
OR mires
OR bog
OR tundra
OR biosphere
OR desert
OR mountain
OR "natural resource"
OR estuary
OR fjord
OR fauna
OR flora
OR soil
OR "coastal waters"
OR wetland
OR freshwater
OR marshland
OR marches
OR dryland
OR seascape
OR landscape
OR coast
OR "arable land"
OR "agricultural land"
OR "natural environment"
OR "environmental resource"
OR agroforest
OR "agro-forest"
OR plantation
OR "protected areas"
OR chaparral
OR sustainable
OR environment
OR conservation
OR ecosystem
OR nature
OR planet
OR Earth
OR biosphere
OR ecological
OR "socio-ecological"
OR restoration
OR wildlife
OR landscape
OR species
OR bioeconomy
OR "resource system"
OR "coupled system"
OR nature

Assessment Corpus

Show the code
#|

cat(params$s_1_tca_corpus)
( biodiversity
OR marine
OR terrestrial
OR forest*
OR woodland*
OR grassland*
OR savanna*
OR shrubland*
OR peatland
OR ecosystem
OR lake
OR river
OR sea
OR ocean
OR meadow
OR heathland
OR mires
OR bog
OR tundra
OR biosphere
OR desert
OR mountain
OR "natural resource"
OR estuary
OR fjord
OR fauna
OR flora
OR soil
OR "coastal waters"
OR wetland
OR freshwater
OR marshland
OR marches
OR dryland
OR seascape
OR landscape
OR coast
OR "arable land"
OR "agricultural land"
OR "natural environment"
OR "environmental resource"
OR agroforest
OR "agro-forest"
OR plantation
OR "protected areas"
OR chaparral
OR sustainable
OR environment
OR conservation
OR ecosystem
OR nature
OR planet
OR Earth
OR biosphere
OR ecological
OR "socio-ecological"
OR restoration
OR wildlife
OR landscape
OR species
OR bioeconomy
OR "resource system"
OR "coupled system"
OR nature ) 
AND 
( (
    (
        (
            transformation
            OR transition
            OR transformative
            OR "transformative change"
        )
        OR (
            (
                shift
                OR change
            )
            AND (
                fundamental
                OR deep
                OR radical
            )
        )
    )
    AND (
        socio
        OR social
        OR politics
        OR political
        OR governance
        OR economic
        OR cultural
        OR system
        OR technological
        OR inner
        OR personal
        OR financial
        OR business
    )
)
OR (
    (
        "transformative change"
        OR "deliberate transformation*"
        OR "transformative turn"
        OR transition
        OR "social-ecological change*"
        OR "deep change"
        OR "fundamental alteration"
        OR "profound change"
        OR "profound transformation"
        OR "radical transformation"
        OR "transformational change"
        OR "complete change"
        OR "complete transformation"
        OR "drastic change"
        OR "in-depth transformation"
        OR "progressive change"
        OR "radical alteration"
        OR "radical change"
        OR "revolutionary change"
        OR "significant modification"
        OR "total transformation"
        OR transition
        OR pathway
        OR power
        OR agency
        OR scale
        OR leverage
        OR context
        OR process
        OR regime
        OR shift
        OR views
        OR value
        OR structure
        OR institution
        OR deliberate
        OR structural
        OR fundamental
        OR system
        OR deep
        OR radical
        OR profound
        OR drastic
        OR widespread
        OR political
        OR economical
        OR structur
        OR complete
        OR progressive
        OR revolutionary
        OR substantial
        OR significant
    )
    AND (
        transformation
        OR alteration
        OR change
        OR turn
        OR action
        OR transition
        OR shift
    )
) )

Chapter 1

01

Show the code
#|

cat(params$s_1_ch1_01)
(
    root
    OR underlying
    OR indirect
)
AND (
    driver
    OR cause
)

02

Show the code
#|

cat(params$s_1_ch1_02)
equity
OR inequity
OR just
OR unjust
OR inequality
OR equality
OR Fair
OR unfair

03

Show the code
#|

cat(params$s_1_ch1_03)
scale
OR impact
OR leapfrog
OR transfer

04

Show the code
#|

cat(params$s_1_ch1_04)
inclusive
OR participation
OR participatory
OR engagement
OR democratic
OR coproduct
OR transdisc
OR multiactor
OR "multi-actor"
OR integrat

05

Show the code
#|

cat(params$s_1_ch1_05)
evaluate
OR reflex
OR reflect
OR monitor
OR adapt
OR learn

06

Show the code
#|

cat(params$s_1_ch1_06)
responsib
OR accountable
OR rights
OR steward
OR reciprocity
OR interdependent
OR interdependency
OR (
    relation
    OR relational
    OR plural
    OR diverse
    OR "sustainability-aligned"
    OR (
        care
        AND (
            value
            OR ethic
        )
    )
)

Chapter 2

Show the code
#|

cat(params$s_1_ch2)
vision
OR future
OR visionary
OR scenarios
OR imagination
OR imagery
OR creativity
OR desire
OR wish
OR visioning
OR process
OR "participaory process"
OR "deliberate process"
OR polics
OR target
OR view
OR value
OR cosmovision
OR cosmocentric
OR dream
OR fiction
OR hope
OR mission
OR objective
OR story
OR worldview
OR aspiration
OR action
OR plan
OR strategy
OR intention
OR model
OR solution
OR innovation
OR perspective
OR platform
OR collective action
OR cooperation
OR consultation
OR coalition
OR response
OR movement
OR effort
OR initiative
OR activity
OR reaction
OR performance
OR operation
OR effect
OR task
OR project
OR influence
OR moment
OR discourse
OR motivation
OR iteration
OR roadmap
OR agenda
OR project
OR programm
OR government
OR technique
OR inspiration
OR culture
OR universe
OR reality
OR fantasy
OR perception
OR visualization
OR approach
OR image
OR arquetype
OR existence
OR cosmology
OR co - production
OR knowledge
OR dialogue
OR transmission
OR conceptual
OR ceremony
OR relationships
OR respect
OR reciprocity
OR responsibilities
OR solidarity
OR harmony
OR self - determination
OR community
OR spiritual
OR languague
OR territory
OR opportunity
OR sight
OR foresight
OR idea
OR appearance

Chapter 3

01

Show the code
#|

cat(params$s_1_ch3_01)
Technology
OR Science
OR "science-society"
OR "science-technology"
OR Solution

02

Show the code
#|

cat(params$s_1_ch3_02)
"co-create"
OR "co-creation"
OR solution
OR knowledge
OR system
OR "t-lab"
OR "technology laboratory"
OR education
OR "socio-technical"

03

Show the code
#|

cat(params$s_1_ch3_03)
System
OR pathways
OR connect
OR Agroecolog
OR Institutional
OR Institution
OR Government

04

Show the code
#|

cat(params$s_1_ch3_04)
inner
OR Personal
OR Religion
OR Love
OR Loving
OR Feelings
OR Stewardship
OR Care
OR Beliefs
OR Belief
OR believe
OR Awareness
OR "Self-Awareness"

05

Show the code
#|

cat(params$s_1_ch3_05)
Worldviews
OR Grassroot
OR "Community-based"
OR Indigenous
OR Leadership
OR "Critical Science"
OR Econfeminism
OR "Political Ecology"
OR Power
OR Agency
OR Environment

06

Show the code
#|

cat(params$s_1_ch3_06)
Economic
OR "Political Economy"
OR institution
OR govern
OR economy
OR governance
OR government
OR globalization
OR states
OR colonial
OR colonialiasism
OR labour
OR organization
OR organisation

Chapter 4

01

Show the code
#|

cat(params$s_1_ch4_01)
(
    challenge
    OR barrier
    OR obstacle
    OR hinder
    OR hindrance
    OR block
    OR prevent
    OR deter
    OR inertia
    OR "path dependence"
    OR "path dependency"
    OR stasis
    OR "lock-in"
    OR trap
    OR habits
    OR habitual
    OR "status quo"
    OR power
    OR "limiting factOR"
)
AND (
    economic inequality
    OR "Wealth concentration"
    OR "Socioeconomic inequality"
    OR financialization
    OR "uneven development"
    OR Financialization
    OR "Structural adjustment"
    OR "Sovereign Debt"
    OR inequality
    OR "Policy effectiveness"
)

02

Show the code
#|

cat(params$s_1_ch4_02)
(
    challenge
    OR barrier
    OR obstacle
    OR hinder
    OR hindrance
    OR block
    OR prevent
    OR deter
    OR inertia
    OR "path dependence"
    OR "path dependency"
    OR stasis
    OR "lock-in"
    OR trap
    OR habits
    OR habitual
    OR status quo
    OR power
    OR "limiting factor"
)
AND (
    "clean technology"
    OR "clean innovation*"
    OR "sustainable innovation"
    OR "sustainable technological innovation"
)
AND (
    "limited access"
    OR "limited availability"
    OR "lack of access"
    OR "unavailability"
)

Chapter 5

Vision

Show the code
#|

cat(params$s_1_ch5_vision)

Case

Show the code
#|

cat(params$s_1_case)
"case study"
OR case
OR "study area"
OR example
OR evaluation
OR concrete
OR empirical
OR practical
OR initiative

Vision & Case

Topics

OpenAlex assigns topics to each work in a hirarchical manner:

Please see here for more information and here for a complete list of all topics and their corresponding subfields, fields and domains.

Methods

Get and calculate Data from OpenAlex

These data is gathered from OpenAlex directly, not using the downloaded TCA Corpus. The data is used to assess the quality of the TCA Corpus.

Show the code
#|

fn <- file.path(".", "data", "tca_corpus", "search_term_hits.rds")
if (!file.exists(fn)) {
    s_t <- grep("s_1_", names(params), value = TRUE)
    search_term_hits <- parallel::mclapply(
        s_t,
        function(stn) {
            message("getting '", stn, "' ...")
            if (grepl("_f_", stn)) {
                search <- params[[stn]]()
            } else {
                search <- params[[stn]]
            }
            search <- compact(search)
            openalexR::oa_query(filter = list(title_and_abstract.search = search)) |>
                openalexR::oa_request(count_only = TRUE, verbose = TRUE) |>
                unlist()
        },
        mc.cores = params$mc.cores,
        mc.preschedule = FALSE
    ) |>
        do.call(what = cbind) |>
        t() |>
        as.data.frame() |>
        dplyr::mutate(page = NULL, per_page = NULL) |>
        dplyr::mutate(count = formatC(count, format = "f", big.mark = ",", digits = 0))

    rownames(search_term_hits) <- s_t |>
        gsub(pattern = "s_1_", replacement = "") |>
        gsub(pattern = "f_", replacement = "") |>
        gsub(pattern = "^ch", replacement = "Chapter ") |>
        gsub(pattern = "_", replacement = " ")

    saveRDS(search_term_hits, file = fn)
} else {
    search_term_hits <- readRDS(fn)
}
Show the code
#|

fn <- file.path(".", "data", "tca_corpus", "key_papers.rds")
if (!file.exists(fn)) {
    key_papers <- lapply(
        params$key_papers,
        function(fn) {
            message("Processing '", fn, "' ...")
            sapply(
                fn,
                function(x) {
                    read.csv(x) |>
                        select(DOI)
                }
            ) |>
                unlist()
        }
    )
    names(key_papers) <- gsub("\\.csv", "", basename(params$key_papers))

    key_papers <- list(
        Ch_1 = unlist(key_papers[grepl("Ch 1 -", names(key_papers))], recursive = FALSE) |> as.vector(),
        Ch_2 = unlist(key_papers[grepl("Ch 2 -", names(key_papers))], recursive = FALSE) |> as.vector(),
        Ch_3_Cl_1 = unlist(key_papers[grepl("Ch 3 - Cl1", names(key_papers))], recursive = FALSE) |> as.vector(),
        Ch_3_Cl_3 = unlist(key_papers[grepl("Ch 3 - Cl3", names(key_papers))], recursive = FALSE) |> as.vector(),
        Ch_3_Cl_4 = unlist(key_papers[grepl("Ch 3 - Cl4", names(key_papers))], recursive = FALSE) |> as.vector(),
        Ch_3_Cl_5 = unlist(key_papers[grepl("Ch 3 - Cl5", names(key_papers))], recursive = FALSE) |> as.vector(),
        Ch_3_Cl_6 = unlist(key_papers[grepl("Ch 3 - Cl6", names(key_papers))], recursive = FALSE) |> as.vector(),
        Ch_3 = unlist(key_papers[grepl("Ch 3 - p", names(key_papers))], recursive = FALSE) |> as.vector(),
        Ch_4_Cl_1 = unlist(key_papers[grepl("Ch 4 - Challenge 1", names(key_papers))], recursive = FALSE) |> as.vector(),
        Ch_4_Cl_2 = unlist(key_papers[grepl("Ch 4 - Challenge 2", names(key_papers))], recursive = FALSE) |> as.vector(),
        Ch_4_Cl_3 = unlist(key_papers[grepl("Ch 4 - Challenge 3", names(key_papers))], recursive = FALSE) |> as.vector(),
        Ch_4_Cl_4 = unlist(key_papers[grepl("Ch 4 - Challenge 4", names(key_papers))], recursive = FALSE) |> as.vector(),
        Ch_4_Cl_5 = unlist(key_papers[grepl("Ch 4 - Challenge 5", names(key_papers))], recursive = FALSE) |> as.vector(),
        Ch_5 = unlist(key_papers[grepl("Ch 5 -", names(key_papers))], recursive = FALSE) |> as.vector()
    )

    saveRDS(key_papers, file = fn)
} else {
    key_papers <- readRDS(fn)
}
Show the code
#|

fn_kw <- file.path(".", "data", "tca_corpus", "key_works.rds")
fn_kw_df <- file.path(".", "data", "tca_corpus", "key_works_df.rds")
if (!all(file.exists(fn_kw, fn_kw_df))) {
    key_works <- parallel::mclapply(
        key_papers,
        function(kp) {
            dois <- kp[kp != ""] |>
                unlist() |>
                tolower() |>
                unique()

            openalexR::oa_fetch(doi = dois, output = "list")
        },
        mc.cores = params$mc.cores,
        mc.preschedule = FALSE
    )

    found <- sapply(
        key_works,
        function(x) {
            length(x) > 0
        }
    )

    key_works <- key_works[found]

    print("The following key paper sets were excluded as they contained no papers in OpenAlex:\n")
    print(names(found)[!found])

    saveRDS(key_works, file = fn_kw)

    key_works_df <- lapply(
        key_works,
        oa2df,
        entity = "works"
    )

    saveRDS(key_works_df, fn_kw_df)
} else {
    key_works <- readRDS(file = fn_kw)
    key_works_df <- readRDS(fn_kw_df)
}
Show the code
#|

fn <- file.path(".", "data", "tca_corpus", "key_works_hits.rds")
if (!file.exists(fn)) {
    kws <- key_works_df
    kws$all  <- key_works_df |>
        bind_rows()

    nms <- names(kws)
    key_works_hits <- pbapply::pblapply(
        nms,
        function(nm) {
            message("Getting key paper set for ", nm, " ...")
            dois <- kws[[nm]] |>
                select(doi) |>
                distinct() |>
                unlist() |>
                unique() |>
                tolower()

            s_t <- grep("s_1_", names(params), value = TRUE)
            kw_h <- parallel::mclapply(
                s_t,
                function(stn) {
                    message("  getting '", stn, "' ...")
                    if (grepl("_f_", stn)) {
                        search <- compact(params[[stn]]())
                    } else {
                        search <- compact(params[[stn]])
                    }
                    get_count(dois = dois, list(title_and_abstract.search = search), verbose = FALSE)
                },
                mc.cores = params$mc.cores,
                mc.preschedule = FALSE
            ) |>
                do.call(what = cbind) |>
                as.data.frame()

            names(kw_h) <- s_t

            # if (ncol(kw_h) == 1){
            #     kw_h <- t(kw_h)
            #     rownames(kw_h) <- dois
            # }

            kw_h <- rbind(
                kw_h,
                colSums(kw_h)
            )

            rownames(kw_h)[[nrow(kw_h)]] <- "Total"
            return(kw_h)  
        }
    )

    names(key_works_hits) <- nms

    for (i in nms) {
        # key_works_hits[[i]] <- cbind(
        #     key_works_hits[[i]],
        #     key_works_hits_tca_filtered[[i]]
        # )

        key_works_hits[[i]] <- cbind(
            key_works_hits[[i]],
            Total = rowSums(key_works_hits[[i]])
        ) |>
            mutate(Total = Total - 1) # |>
            # relocate(tca_corpus_SDG, .after = s_1_tca_corpus)
    }

    ###

    saveRDS(key_works_hits, file = fn)
} else {
    key_works_hits <- readRDS(file = fn)
}

Download TCA Corpus

The corpus download will be stored in data/pages and the arrow database in data/corpus.

This is not on github!

The corpus can be read by running get_corpus() which o[pens the database so that then it can be fed into a dplyr pipeline. After most dplyr functions, the actual data needs to be collected via collect().

Only then is the actual data read!

Needs to be enabled by setting eval: true in the code block below.

Show the code
#|

tic()

IPBES.R::corpus_download(
    pages_dir = params$pages_dir,
    title_and_abstract_search = compact(params$s_1_tca_corpus),
    continue = TRUE,
    delete_pages_dir = FALSE,
    set_size = 2000,
    dry_run = FALSE,
    verbose = TRUE,
    mc_cores = 6
)

toc()
Show the code
tic()

IPBES.R::corpus_pages_to_arrow(
    pages_dir = params$pages_dir,
    arrow_dir = params$corpus_dir,
    continue = TRUE,
    delete_arrow_dir = FALSE,
    dry_run = FALSE,
    verbose = TRUE,
    mc_cores = 2
)

toc()
Show the code
#|

years <- IPBES.R::corpus_read(params$corpus_dir) |>
    distinct(publication_year) |>
    collect() |>
    unlist() |>
    as.vector() |>
    sort()

lapply(
    years,
    function(y) {
        message("\nProcessing year: ", y)
        tic()
        dataset <- IPBES.R::corpus_read(params$corpus_dir) |>
            dplyr::filter(publication_year == y) |>
            dplyr::collect() |>
            group_by(id) |>
            slice_max(
                publication_year,
                n = 1,
                with_ties = FALSE,
                na_rm = TRUE
            )
        unlink(
            file.path(params$corpus_dir, paste0("publication_year=", y)),
            recursive = TRUE,
            force = TRUE
        )
        arrow::write_dataset(
            dataset = dataset,
            path = params$corpus_dir,
            partitioning = c("publication_year", "set"),
            format = "parquet",
            existing_data_behavior = "overwrite"
        )
        toc()
    }
)

Prepare Full Text search of Title and Abstract

This is done using duckDB and the fts extension which is a full text search extension for duckDB (see also for details and for arrow / parquet support).

The following steps are conducted:

  1. Create new duckDB called tca_corpus.duckdb
    • import data needed
    • create fts index for full text search
Show the code
if (!file.exists(params$duckdb_fn)) {
    sql <- paste0(
        "CREATE TABLE tca_corpus AS SELECT id, author_abbr, publication_year, doi, display_name, ab FROM parquet_scan('",
        file.path(".", "data", "tca_corpus", "corpus", "**", "*.parquet"),
        "')"
    )

    con <- duckdb::dbConnect(duckdb::duckdb(), dbdir = params$duckdb_fn, read_only = FALSE)
    #
    dbExecute(con, "SET autoinstall_known_extensions=1")
    dbExecute(con, "SET autoload_known_extensions=1")
    dbExecute(con, sql)
    #
    duckdb::dbDisconnect(con, shutdown = TRUE)

    con <- duckdb::dbConnect(duckdb::duckdb(), dbdir = params$duckdb_fn, read_only = FALSE)
    #
    dbExecute(con, "INSTALL fts")
    dbExecute(con, "LOAD fts")

    input_table <- "tca_corpus"
    input_id <- "id"
    input_values <- "'display_name', 'ab'"

    sql <- paste0("PRAGMA create_fts_index(", input_table, ", ", input_id, ", ", input_values, ", overwrite=1);")

    dbExecute(con, sql)
    #
    duckdb::dbDisconnect(con, shutdown = TRUE)
}

# con <- dbConnect(duckdb::duckdb(params$duckdb_fn))

# SQL <- "SELECT * FROM tca_corpus WHERE display_name MATCH 'transformative';"
# dbListTables(con)

#     input_table <- "tca_corpus"
#     input_id <- "id"
#     input_values <- "'display_name', 'ab'"

#     query_string <- "'case study'"
#     fields <- "'display_name', 'ab'"

# sql <- paste0("SELECT fts_main_tca_corpus.match_bm25(", input_id, ", ", query_string, ", fields = ", fields, " FROM tca_corpus)"

# dbExecute(con, sql)

# duckdb::dbDisconnect(con, shutdown = TRUE)

Extract Data from Global Corpus

Export

Show the code
#|

sample_size <- 250

fn <- file.path("data", "tca_corpus", paste0("random_", sample_size, "_tca_corpus.xlsx"))
if (!file.exists(fn)) {
    set.seed(13)
    read_corpus(params$corpus_dir) |>
        dplyr::select(
            id,
            doi,
            author = author_abbr,
            title = display_name,
            abstract = ab
        ) |>
        dplyr::slice_sample(
            n = sample_size
        ) |>
        dplyr::mutate(
            abstract = substr(abstract, 1, 5000)
        ) |>
        dplyr::collect() |>
        writexl::write_xlsx(path = fn)
}

Sectors

The Sectors definition is based on the subfields assigned to each work by OpenAlex. These were grouped by experts into sectors. See this Google Doc for details.

Show the code
#|

if (!dir.exists(params$corpus_topics_dir)) {

    con <- duckdb::dbConnect(duckdb::duckdb(), read_only = FALSE)

    corpus_read(params$corpus_dir) |>
        arrow::to_duckdb(table_name = "corpus", con = con) |>
        invisible()
    corpus_read(file.path("inputs", "tca_corpus", "sectors_def.parquet")) |>
        arrow::to_duckdb(table_name = "sectors", con = con) |>
        invisible()

    paste0(
        "CREATE VIEW corpus_unnest AS ",
        "SELECT  ",
        "corpus.id AS work_id,  ",
        "corpus.publication_year AS publication_year,  ",
        "UNNEST(topics).i AS i,  ",
        "UNNEST(topics).score AS score,  ",
        "UNNEST(topics).name AS name, ",
        "UNNEST(topics).id AS id,  ",
        "UNNEST(topics).display_name AS display_name  ",
        "FROM  ",
        "corpus "
    ) |>
    dbExecute(conn = con)

    select_sql <- paste0(
        "SELECT ",
        "corpus_unnest.*, ",
        "sectors.sector ",
        "FROM ",
        "corpus_unnest ",
        "LEFT JOIN ",
        "sectors ",
        "ON ",
        "corpus_unnest.id  == sectors.id "
    )

    dbGetQuery(con, paste(select_sql, "LIMIT 10"))

    sql <- paste0(
        "COPY ( ",
        select_sql,
        ") TO '", params$corpus_topics_dir, "' ",
        "(FORMAT PARQUET, COMPRESSION 'SNAPPY', PARTITION_BY 'publication_year')"
    )

    dbExecute(con, sql)

    duckdb::dbDisconnect(con, shutdown = TRUE)

    ###########################

    # years <- IPBES.R::corpus_read(params$corpus_dir) |>
    #     distinct(publication_year) |>
    #     collect() |>
    #     unlist() |>
    #     as.vector() |>
    #     sort()

    # sectors <- read.csv(file.path("inputs", "tca_corpus", "sectors_def.csv")) |>
    #     tibble::as_tibble() |>
    #     dplyr::mutate(
    #         id = paste0("https://openalex.org/subfields/", id),
    #         display_name = NULL
    #     )

    # pbmcapply::pbmclapply(
    #     years,
    #     function(y) {
    #         message("\nProcessing year: ", y)
    #         IPBES.R::corpus_read(params$corpus_dir) |>
    #             dplyr::filter(publication_year == y) |>
    #             dplyr::select(
    #                 id,
    #                 publication_year,
    #                 topics
    #             ) |>
    #             collect() |>
    #             IPBES.R::extract_topics(
    #                 names = "subfield"
    #             ) |>
    #             dplyr::left_join(
    #                 y = sectors,
    #                 by = "id"
    #             ) |>
    #             arrow::write_dataset(
    #                 path = params$corpus_topics_dir,
    #                 partitioning = c("publication_year"),
    #                 format = "parquet",
    #                 existing_data_behavior = "overwrite"
    #             )
    #     },
    #     mc.cores = 3,
    #     mc.preschedule = FALSE
    # )
}

Authors

Show the code
#|

if (!dir.exists(params$corpus_authors_dir)) {
    con <- duckdb::dbConnect(duckdb::duckdb(), read_only = FALSE)

    corpus_read(params$corpus_dir) |>
        arrow::to_duckdb(table_name = "corpus", con = con) |>
        invisible()

    paste0(
        "CREATE VIEW corpus_unnest AS ",
        "SELECT  ",
        "corpus.id AS work_id,  ",
        "corpus.publication_year AS publication_year,  ",
        "UNNEST(author).au_id AS au_id,  ",
        "UNNEST(author).au_display_name AS au_display_name, ",
        "UNNEST(author).au_orcid AS au_orcid,  ",
        "UNNEST(author).author_position AS author_position,  ",
        "UNNEST(author).is_corresponding AS is_corresponding,  ",
        "UNNEST(author).au_affiliation_raw AS au_affiliation_raw,  ",
        "UNNEST(author).institution_id AS institution_id,  ",
        "UNNEST(author).institution_display_name AS institution_display_name,  ",
        "UNNEST(author).institution_ror AS institution_ror,  ",
        "UNNEST(author).institution_country_code AS institution_country_code,  ",
        "UNNEST(author).institution_type AS institution_type,  ",
        "UNNEST(author).institution_lineage AS institution_lineage  ",
        "FROM  ",
        "corpus "
    ) |> dbExecute(conn = con)

    paste0(
        "COPY ( ",
        "SELECT * FROM corpus_unnest ",
        ") TO '", params$corpus_authors_dir, "' ",
        "(FORMAT PARQUET, COMPRESSION 'SNAPPY', PARTITION_BY 'publication_year')"
    ) |>
        dbExecute(conn = con)

    duckdb::dbDisconnect(con, shutdown = TRUE)

    ###################################

    # dir.create(params$corpus_authors_dir, showWarnings = FALSE)

    # years <- IPBES.R::corpus_read(params$corpus_dir) |>
    #     distinct(publication_year) |>
    #     collect() |>
    #     unlist() |>
    #     as.vector() |>
    #     sort()

    # pbmcapply::pbmclapply(
    #     years,
    #     function(y) {
    #         message("\nProcessing year: ", y)
    #         IPBES.R::corpus_read(params$corpus_dir) |>
    #             dplyr::filter(publication_year == y) |>
    #             dplyr::select(
    #                 id,
    #                 publication_year,
    #                 author
    #             ) |>
    #             collect() |>
    #             IPBES.R::extract_authors(
    #                 positions = TRUE
    #             ) |>
    #             arrow::write_dataset(
    #                 path = params$corpus_authors_dir,
    #                 partitioning = c("publication_year"),
    #                 format = "parquet",
    #                 existing_data_behavior = "overwrite"
    #             )
    #     },
    #     mc.cores = 3,
    #     mc.preschedule = FALSE
    # )
}

Primary Topics

Show the code
fn <- file.path(".", "data", "tca_corpus", paste0("prim_topics_tca_corpus.rds"))
if (!file.exists(fn)) {
    prim_topics_tca_corpus <- corpus_read(params$corpus_topics_dir) |>
        dplyr::filter(
            name == "topic",
            i == 1
        ) |>
        mutate(
            id = as.integer(sub("https://openalex.org/T", "", id))
        ) |>
        dplyr::group_by(id) |>
        summarize(
            count = n()
        ) |>
        dplyr::left_join(
            read.csv(file.path("inputs", "tca_corpus", "OpenAlex_topic_mapping_table - final_topic_field_subfield_table.csv")),
            by = c("id" = "topic_id")
        ) |>
        dplyr::arrange(desc(count)) |>
        collect()

    saveRDS(prim_topics_tca_corpus, file = fn)
} else {
    prim_topics_tca_corpus <- readRDS(fn)
}

Figures

Show the code
#|

fn <- file.path(".", "data", "tca_corpus", "publications_over_time_tca_corpus.rds")

if (!file.exists(fn)) {
read_corpus(params$corpus_dir) |>
    dplyr::select(publication_year) |>
    dplyr::arrange(publication_year) |>
    dplyr::collect() |>
    table() |>
    as.data.frame() |>
    mutate(
        publication_year = as.integer(as.character(publication_year)),
        p = Freq / sum(Freq),
        p_cum = cumsum(p)
    ) |>
    rename(
        count = Freq
    ) |>
    dplyr::inner_join(
        y = openalexR::oa_fetch(
            search = "",
            group_by = "publication_year",
            output = "tibble",
            verbose = FALSE
        ) |>
            dplyr::select(
                key,
                count
            ) |>
            dplyr::rename(
                publication_year = key,
                count_oa = count
            ) |>
            dplyr::arrange(publication_year) |>
            dplyr::mutate(
                publication_year = as.integer(as.character(publication_year)),
                p_oa = count_oa / sum(count_oa),
                p_oa_cum = cumsum(p_oa)
            )
    ) |>
    saveRDS(file = fn)
}
Show the code
#|

if (length(list.files(file.path("figures", "tca_corpus"), pattern = "publications_over_time")) < 2) {
    figure <- readRDS(file.path(".", "data", "tca_corpus", "publications_over_time_tca_corpus.rds")) |>
        dplyr::filter(publication_year >= 1900) |>
        ggplot() +
        geom_bar(aes(x = publication_year, y = p), stat = "identity") +
        geom_line(aes(x = publication_year, y = p_cum / 10), color = "red") +
        geom_line(aes(x = publication_year, y = p_oa_cum / 10), color = "blue") +
        scale_x_continuous(breaks = seq(1900, 2020, 10)) +
        scale_y_continuous(
            "Proportion of publications",
            sec.axis = sec_axis(~ . * 10, name = "Cumulative proportion") # divide by 100 to scale back the secondary axis
        ) +
        labs(
            title = "Publications over time",
            x = "Year",
            y = "Number of publications"
        ) +
        theme_minimal() +
        theme(axis.text.y.right = element_text(color = "red"))

    ggplot2::ggsave(
        file.path("figures", "tca_corpus", "publications_over_time.pdf"),
        width = 12,
        height = 6,
        figure
    )
    ggplot2::ggsave(
        file.path("figures", "tca_corpus", "publications_over_time.png"),
        width = 12,
        height = 6,
        figure
    )

    rm(figure)
}

Maps

Show the code
#|

fn <- file.path(".", "data", "tca_corpus", "countries_tca_corpus.rds")
if (!file.exists(fn)) {
    corpus <- corpus_read(params$corpus_authors_dir)

    data_first <- corpus |>
        dplyr::filter(
            author_position == "first"
        ) |>
        dplyr::select(
            work_id,
            institution_country_code,
        ) |>
        dplyr::group_by(
            work_id,
            institution_country_code
        ) |>
        dplyr::summarise(
            count_first = 1 / n(),
            .groups = "drop"
        ) |>
        dplyr::group_by(
            institution_country_code
        ) |>
        dplyr::summarise(
            count = sum(count_first),
            .groups = "drop"
        ) |>
        dplyr::mutate(
            position = "first"
        )

    data_all <- corpus |>
        dplyr::select(
            work_id,
        ) |>
        dplyr::group_by(
            work_id,
        ) |>
        dplyr::summarize(
            count = n()
        ) |>
        dplyr::right_join(
            y = corpus |>
                dplyr::select(
                    work_id,
                    institution_country_code
                ),
            by = "work_id"
        ) |>
        dplyr::group_by(
            institution_country_code
        ) |>
        dplyr::summarise(
            count = sum(count),
            .groups = "drop"
        ) |>
        dplyr::mutate(
            position = "all"
        )

    data_oa <- openalexR::oa_fetch(
        group_by = "authorships.countries",
        output = "tibble",
        verbose = FALSE
    ) |>
        dplyr::mutate(
            iso3c = countrycode::countrycode(
                key_display_name,
                origin = "country.name",
                destination = "iso3c"
            ),
            key_display_name = NULL,
            key = NULL,
            position = "oa"
        )

    data <- dplyr::add_row(
        collect(data_first),
        collect(data_all)
    ) |>
        dplyr::mutate(
            iso3c = countrycode::countrycode(
                institution_country_code,
                origin = "iso2c",
                destination = "iso3c"
            ),
            institution_country_code = NULL
        ) |>
        dplyr::add_row(
            data_oa
        ) |>
    saveRDS(file = fn)
    rm(data_first, data_all, data_oa)
}
Show the code
#|

if (length(list.files(path = file.path("maps", "tca_corpus"), pattern = "publications_countries")) < 2) {
    data <- readRDS(file.path(".", "data", "tca_corpus", "countries_tca_corpus.rds")) |>
        dplyr::group_by(iso3c) |>
        dplyr::summarize(
            count_first = sum(count[position == "first"], na.rm = TRUE),
            count_all = sum(count[position == "all"], na.rm = TRUE),
            count_oa = sum(count[position == "oa"], na.rm = TRUE)
        ) |>
        dplyr::mutate(
            count_oa = ifelse(is.na(count_oa), 0, count_oa),
            log_count_oa = log(count_oa + 1),
            p_oa = count_oa / sum(count_oa),
            #
            count_first = ifelse(is.na(count_first), 0, count_first),
            log_count_first = log(count_first + 1),
            p_first = count_first / sum(count_first),
            p_first_output = count_first / count_oa,
            p_first_diff = (p_oa - p_first) * 100,
            #
            count_all = ifelse(is.na(count_all), 0, count_all),
            log_count_all = log(count_all + 1),
            p_all = count_all / sum(count_all),
            p_all_output = count_all / count_oa,
            p_all_diff = (p_oa - p_all) * 100,
        )

        # data |> mutate(
        #     count_first = count_first / max(count_first),
        #     count_all = count_all / max(count_all),
        #     count_oa = count_oa / max(count_oa)
        # ) |>
        # dplyr::arrange(desc(count_oa)) |>
        # ggplot(aes(x = iso3c)) +
        #     geom_line(aes(y = count_first, color = "Count First"), group = 1) +
        #     geom_line(aes(y = count_all, color = "Count All"), group = 1) +
        #     geom_line(aes(y = count_oa, color = "Count OA"), group = 1) +
        #     scale_color_manual(values = c("Count First" = "red", "Count All" = "blue", "Count OA" = "green")) +
        #     labs(x = "ISO3C", y = "Normalized Count") +
        #     theme_minimal()

    map <- patchwork::wrap_plots(
        data |>
            IPBES.R::map_country_codes(
                map_type = "countries",
                values = "count_oa",
                geodata_path = params$gdm_dir
            ) +
            ggplot2::scale_fill_gradient2(low = "#E69F00", high = "#56B4E9") +
            ggplot2::ggtitle("count of overall publications (count_oa)"),
        #
        data |>
            IPBES.R::map_country_codes(
                map_type = "countries",
                values = "count_first",
                geodata_path = params$gdm_dir
            ) +
            ggplot2::scale_fill_gradient2(low = "#E69F00", high = "#56B4E9") +
            ggplot2::ggtitle("count of TCA publications (count_first)"),
        #
        data |>
            IPBES.R::map_country_codes(
                map_type = "countries",
                values = "count_all",
                geodata_path = params$gdm_dir
            ) +
            ggplot2::scale_fill_gradient2(low = "#E69F00", high = "#56B4E9") +
            ggplot2::ggtitle("count of TCA publications (count_all)"),
        ####
        data |>
            IPBES.R::map_country_codes(
                map_type = "countries",
                values = "log_count_oa",
                geodata_path = params$gdm_dir
            ) +
            ggplot2::scale_fill_gradient2(low = "#E69F00", high = "#56B4E9") +
            ggplot2::ggtitle("log(count + 1) of overall publications (log_count_oa)"),
        #
        data |>
            IPBES.R::map_country_codes(
                map_type = "countries",
                values = "log_count_first",
                geodata_path = params$gdm_dir
            ) +
            ggplot2::scale_fill_gradient2(low = "#E69F00", high = "#56B4E9") +
            ggplot2::ggtitle("log(count + 1) of TCA publications (log_count_first)"),
        #
        data |>
            IPBES.R::map_country_codes(
                map_type = "countries",
                values = "log_count_all",
                geodata_path = params$gdm_dir
            ) +
            ggplot2::scale_fill_gradient2(low = "#E69F00", high = "#56B4E9") +
            ggplot2::ggtitle("log(count + 1) of TCA publications (log_count_all)"),
        ####
        data |>
            IPBES.R::map_country_codes(
                map_type = "countries",
                values = "p_oa",
                geodata_path = params$gdm_dir
            ) +
            ggplot2::scale_fill_gradient2(low = "#E69F00", high = "#56B4E9") +
            ggplot2::ggtitle("Overall research output (p_oa)"),
        #
        data |>
            IPBES.R::map_country_codes(
                map_type = "countries",
                values = "p_first",
                geodata_path = params$gdm_dir
            ) +
            ggplot2::scale_fill_gradient2(low = "#E69F00", high = "#56B4E9") +
            ggplot2::ggtitle("TCA research output (p_first)"),
        #
        data |>
            IPBES.R::map_country_codes(
                map_type = "countries",
                values = "p_all",
                geodata_path = params$gdm_dir
            ) +
            ggplot2::scale_fill_gradient2(low = "#E69F00", high = "#56B4E9") +
            ggplot2::ggtitle("TCA research output (p_all)"),
        ####
        ggplot() +
            theme_void(),
        data |>
            IPBES.R::map_country_codes(
                map_type = "countries",
                values = "p_first_diff",
                geodata_path = params$gdm_dir
            ) +
            ggplot2::scale_fill_gradient2(low = "#E69F00", mid = "white", high = "#56B4E9", midpoint = 0) +
            ggplot2::ggtitle("difference (TCA - overall) output (p_oa - p_first)"),
        #
        data |>
            IPBES.R::map_country_codes(
                map_type = "countries",
                values = "p_all_diff",
                geodata_path = params$gdm_dir
            ) +
            ggplot2::scale_fill_gradient2(low = "#E69F00", mid = "white", high = "#56B4E9", midpoint = 0) +
            ggplot2::ggtitle("difference (TCA - overall) output (p_oa - p_all)"),
        ncol = 3
    )

    ggplot2::ggsave(
        file.path("maps", "tca_corpus", "publications_countries.pdf"),
        width = 12,
        height = 8,
        map
    )
    ggplot2::ggsave(
        file.path("maps", "tca_corpus", "publications_countries.png"),
        width = 12,
        height = 8,
        map
    )
}
Show the code
if (length(list.files(path = file.path("maps", "tca_corpus"), pattern = "publications_countries_before_2016")) < 2) {
    data <- readRDS(file.path(".", "data", "tca_corpus", "countries_tca_corpus.rds")) |>
        dplyr::filter(
            publication_year < 2016
        ) |>
        dplyr::group_by(iso3c) |>
        dplyr::summarize(
            count_first = sum(as.integer(count_first), na.rm = TRUE),
            count_all = sum(as.integer(count_all), na.rm = TRUE),
            count_oa = sum(as.integer(count_oa), na.rm = TRUE),
        ) |>
        dplyr::mutate(
            count_oa = ifelse(is.na(count_oa), 0, count_oa),
            log_count_oa = log(count_oa + 1),
            p_oa = count_oa / sum(count_oa),
            #
            count_first = ifelse(is.na(count_first), 0, count_first),
            log_count_first = log(count_first + 1),
            p_first = count_first / sum(count_first),
            p_first_output = count_first / count_oa,
            p_first_diff = (p_oa - p_first) * 100,
            #
            count_all = ifelse(is.na(count_all), 0, count_all),
            log_count_all = log(count_all + 1),
            p_all = count_all / sum(count_all),
            p_all_output = count_all / count_oa,
            p_all_diff = (p_oa - p_all) * 100,
        )

    map <- patchwork::wrap_plots(
        data |>
            IPBES.R::map_country_codes(
                map_type = "countries",
                values = "count_oa",
                geodata_path = params$gdm_dir
            ) +
            ggplot2::scale_fill_gradient2(low = "#E69F00", high = "#56B4E9") +
            ggplot2::ggtitle("count of overall publications (count_oa)"),
        #
        data |>
            IPBES.R::map_country_codes(
                map_type = "countries",
                values = "count_first",
                geodata_path = params$gdm_dir
            ) +
            ggplot2::scale_fill_gradient2(low = "#E69F00", high = "#56B4E9") +
            ggplot2::ggtitle("count of TCA publications (count_first)"),
        #
        data |>
            IPBES.R::map_country_codes(
                map_type = "countries",
                values = "count_all",
                geodata_path = params$gdm_dir
            ) +
            ggplot2::scale_fill_gradient2(low = "#E69F00", high = "#56B4E9") +
            ggplot2::ggtitle("count of TCA publications (count_all)"),
        ####
        data |>
            IPBES.R::map_country_codes(
                map_type = "countries",
                values = "log_count_oa",
                geodata_path = params$gdm_dir
            ) +
            ggplot2::scale_fill_gradient2(low = "#E69F00", high = "#56B4E9") +
            ggplot2::ggtitle("log(count + 1) of overall publications (log_count_oa)"),
        #
        data |>
            IPBES.R::map_country_codes(
                map_type = "countries",
                values = "log_count_first",
                geodata_path = params$gdm_dir
            ) +
            ggplot2::scale_fill_gradient2(low = "#E69F00", high = "#56B4E9") +
            ggplot2::ggtitle("log(count + 1) of TCA publications (log_count_first)"),
        #
        data |>
            IPBES.R::map_country_codes(
                map_type = "countries",
                values = "log_count_all",
                geodata_path = params$gdm_dir
            ) +
            ggplot2::scale_fill_gradient2(low = "#E69F00", high = "#56B4E9") +
            ggplot2::ggtitle("log(count + 1) of TCA publications (log_count_all)"),
        ####
        data |>
            IPBES.R::map_country_codes(
                map_type = "countries",
                values = "p_oa",
                geodata_path = params$gdm_dir
            ) +
            ggplot2::scale_fill_gradient2(low = "#E69F00", high = "#56B4E9") +
            ggplot2::ggtitle("Overall research output (p_oa)"),
        #
        data |>
            IPBES.R::map_country_codes(
                map_type = "countries",
                values = "p_first",
                geodata_path = params$gdm_dir
            ) +
            ggplot2::scale_fill_gradient2(low = "#E69F00", high = "#56B4E9") +
            ggplot2::ggtitle("TCA research output (p_first)"),
        #
        data |>
            IPBES.R::map_country_codes(
                map_type = "countries",
                values = "p_all",
                geodata_path = params$gdm_dir
            ) +
            ggplot2::scale_fill_gradient2(low = "#E69F00", high = "#56B4E9") +
            ggplot2::ggtitle("TCA research output (p_all)"),
        ####
        ggplot() +
            theme_void(),
        data |>
            IPBES.R::map_country_codes(
                map_type = "countries",
                values = "p_first_diff",
                geodata_path = params$gdm_dir
            ) +
            ggplot2::scale_fill_gradient2(low = "#E69F00", mid = "white", high = "#56B4E9", midpoint = 0) +
            ggplot2::ggtitle("difference (TCA - overall) output (p_oa - p_first)"),
        #
        data |>
            IPBES.R::map_country_codes(
                map_type = "countries",
                values = "p_all_diff",
                geodata_path = params$gdm_dir
            ) +
            ggplot2::scale_fill_gradient2(low = "#E69F00", mid = "white", high = "#56B4E9", midpoint = 0) +
            ggplot2::ggtitle("difference (TCA - overall) output (p_oa - p_all)"),
        ncol = 3
    )

    ggplot2::ggsave(
        file.path("maps", "tca_corpus", "publications_countries_before_2016.pdf"),
        width = 12,
        height = 8,
        map
    )
    ggplot2::ggsave(
        file.path("maps", "tca_corpus", "publications_countries_before_2016.png"),
        width = 12,
        height = 8,
        map
    )
}
Show the code
if (length(list.files(path = file.path("maps", "tca_corpus"), pattern = "publications_countries_after_2019")) < 2) {
    data <- readRDS(file.path(".", "data", "tca_corpus", "countries_tca_corpus.rds")) |>
        dplyr::filter(
            publication_year > 2019
        ) |>
        dplyr::group_by(iso3c) |>
        dplyr::summarize(
            count_first = sum(as.integer(count_first), na.rm = TRUE),
            count_all = sum(as.integer(count_all), na.rm = TRUE),
            count_oa = sum(as.integer(count_oa), na.rm = TRUE),
        ) |>
        dplyr::mutate(
            count_oa = ifelse(is.na(count_oa), 0, count_oa),
            log_count_oa = log(count_oa + 1),
            p_oa = count_oa / sum(count_oa),
            #
            count_first = ifelse(is.na(count_first), 0, count_first),
            log_count_first = log(count_first + 1),
            p_first = count_first / sum(count_first),
            p_first_output = count_first / count_oa,
            p_first_diff = (p_oa - p_first) * 100,
            #
            count_all = ifelse(is.na(count_all), 0, count_all),
            log_count_all = log(count_all + 1),
            p_all = count_all / sum(count_all),
            p_all_output = count_all / count_oa,
            p_all_diff = (p_oa - p_all) * 100,
        )

    map <- patchwork::wrap_plots(
        data |>
            IPBES.R::map_country_codes(
                map_type = "countries",
                values = "count_oa",
                geodata_path = params$gdm_dir
            ) +
            ggplot2::scale_fill_gradient2(low = "#E69F00", high = "#56B4E9") +
            ggplot2::ggtitle("count of overall publications (count_oa)"),
        #
        data |>
            IPBES.R::map_country_codes(
                map_type = "countries",
                values = "count_first",
                geodata_path = params$gdm_dir
            ) +
            ggplot2::scale_fill_gradient2(low = "#E69F00", high = "#56B4E9") +
            ggplot2::ggtitle("count of TCA publications (count_first)"),
        #
        data |>
            IPBES.R::map_country_codes(
                map_type = "countries",
                values = "count_all",
                geodata_path = params$gdm_dir
            ) +
            ggplot2::scale_fill_gradient2(low = "#E69F00", high = "#56B4E9") +
            ggplot2::ggtitle("count of TCA publications (count_all)"),
        ####
        data |>
            IPBES.R::map_country_codes(
                map_type = "countries",
                values = "log_count_oa",
                geodata_path = params$gdm_dir
            ) +
            ggplot2::scale_fill_gradient2(low = "#E69F00", high = "#56B4E9") +
            ggplot2::ggtitle("log(count + 1) of overall publications (log_count_oa)"),
        #
        data |>
            IPBES.R::map_country_codes(
                map_type = "countries",
                values = "log_count_first",
                geodata_path = params$gdm_dir
            ) +
            ggplot2::scale_fill_gradient2(low = "#E69F00", high = "#56B4E9") +
            ggplot2::ggtitle("log(count + 1) of TCA publications (log_count_first)"),
        #
        data |>
            IPBES.R::map_country_codes(
                map_type = "countries",
                values = "log_count_all",
                geodata_path = params$gdm_dir
            ) +
            ggplot2::scale_fill_gradient2(low = "#E69F00", high = "#56B4E9") +
            ggplot2::ggtitle("log(count + 1) of TCA publications (log_count_all)"),
        ####
        data |>
            IPBES.R::map_country_codes(
                map_type = "countries",
                values = "p_oa",
                geodata_path = params$gdm_dir
            ) +
            ggplot2::scale_fill_gradient2(low = "#E69F00", high = "#56B4E9") +
            ggplot2::ggtitle("Overall research output (p_oa)"),
        #
        data |>
            IPBES.R::map_country_codes(
                map_type = "countries",
                values = "p_first",
                geodata_path = params$gdm_dir
            ) +
            ggplot2::scale_fill_gradient2(low = "#E69F00", high = "#56B4E9") +
            ggplot2::ggtitle("TCA research output (p_first)"),
        #
        data |>
            IPBES.R::map_country_codes(
                map_type = "countries",
                values = "p_all",
                geodata_path = params$gdm_dir
            ) +
            ggplot2::scale_fill_gradient2(low = "#E69F00", high = "#56B4E9") +
            ggplot2::ggtitle("TCA research output (p_all)"),
        ####
        ggplot() +
            theme_void(),
        data |>
            IPBES.R::map_country_codes(
                map_type = "countries",
                values = "p_first_diff",
                geodata_path = params$gdm_dir
            ) +
            ggplot2::scale_fill_gradient2(low = "#E69F00", mid = "white", high = "#56B4E9", midpoint = 0) +
            ggplot2::ggtitle("difference (TCA - overall) output (p_oa - p_first)"),
        #
        data |>
            IPBES.R::map_country_codes(
                map_type = "countries",
                values = "p_all_diff",
                geodata_path = params$gdm_dir
            ) +
            ggplot2::scale_fill_gradient2(low = "#E69F00", mid = "white", high = "#56B4E9", midpoint = 0) +
            ggplot2::ggtitle("difference (TCA - overall) output (p_oa - p_all)"),
        ncol = 3
    )

    ggplot2::ggsave(
        file.path("maps", "tca_corpus", "publications_countries_after_2019.pdf"),
        width = 12,
        height = 8,
        map
    )
    ggplot2::ggsave(
        file.path("maps", "tca_corpus", "publications_countries_after_2019.png"),
        width = 12,
        height = 8,
        map
    )
}

Topics and Sectors

Show the code
#|

fn <- file.path("data", "tca_corpus", "sectors_over_time.rds")
if (!file.exists(fn)) {
    data <- IPBES.R::corpus_read(params$corpus_topics_dir) |>
        dplyr::filter(
            name == "subfield"
        ) |>
        dplyr::group_by(
            publication_year,
            sector,
            i
        ) |>
        dplyr::summarize(
            count = n(),
            .groups = "drop"
        ) |>
        dplyr::rename(
            level = i
        ) |>
        dplyr::collect()

    data |>
        dplyr::filter(
            level == 1
        ) |>
        dplyr::group_by(
            publication_year,
            sector
        ) |>
        dplyr::summarize(
            count_1 = sum(count),
            .groups = "drop"
        ) |>
        dplyr::full_join(
            data |>
                dplyr::group_by(
                    publication_year,
                    sector
                ) |>
                dplyr::summarize(
                    count_all = sum(count)
                )
        ) |>
        dplyr::arrange(
            publication_year,
            sector
        ) |>
        dplyr::mutate(
            count_1 = ifelse(is.na(count_1), 0, count_1),
            count_all = ifelse(is.na(count_all), 0, count_all)
        ) |>
        dplyr::group_by(sector) |>
        dplyr::mutate(
            cumsum_count_1 = cumsum(count_1),
            cumsum_count_all = cumsum(count_all),
            p_cumsum_count_1 = cumsum_count_1 / max(cumsum_count_1),
            p_cumsum_count_all = cumsum_count_all / max(cumsum_count_all)
        ) |>
        saveRDS(fn)
    rm(data)
}
Show the code
#|

if (length(list.files(file.path("figures", "tca_corpus"), pattern = "sectors_over_time")) < 2) {
    figure_1 <- readRDS(file.path(file.path("data", "tca_corpus", "sectors_over_time.rds"))) |>
        dplyr::filter(
            publication_year >= 1950
        ) |>
        ggplot() +
        geom_line(
            aes(
                x = publication_year,
                y = cumsum_count_1,
                color = sector,
                lty = sector
            )
        ) +
        scale_x_continuous(breaks = seq(1900, 2020, 10)) +
        scale_y_continuous(
            "Log(No Publications)",
            trans = "log10"
            # sec.axis = sec_axis(~ . * 10, name = "Cumulative proportion") # divide by 100 to scale back the secondary axis
        ) +
        labs(
            title = "Publications classified into Sectors over time (primary sector only)",
            x = "Year"
            # y = "Number of publications"
        ) +
        theme_minimal() +
        theme(
            legend.position = "bottom",
            # axis.text.y.right = element_text(color = "red")
        )

    figure_all <- readRDS(file.path(file.path("data", "tca_corpus", "sectors_over_time.rds"))) |>
        dplyr::filter(
            publication_year >= 1950
        ) |>
        ggplot() +
        geom_line(
            aes(
                x = publication_year,
                y = cumsum_count_all,
                color = sector,
                lty = sector
            )
        ) +
        scale_x_continuous(breaks = seq(1900, 2020, 10)) +
        scale_y_continuous(
            "Log(No Publications)",
            trans = "log10"
            # sec.axis = sec_axis(~ . * 10, name = "Cumulative proportion") # divide by 100 to scale back the secondary axis
        ) +
        labs(
            title = "Publications clssified into Sectors over time (up to three sectors)",
            x = "Year"
            # y = "Number of publications"
        ) +
        theme_minimal() +
        theme(
            legend.position = "none",
            # axis.text.y.right = element_text(color = "red")
        )

    figure <- patchwork::wrap_plots(
        figure_1,
        figure_all,
        nrow = 2
    )

    ggplot2::ggsave(
        file.path("figures", "tca_corpus", "sectors_over_time.pdf"),
        width = 12,
        height = 12,
        figure
    )
    ggplot2::ggsave(
        file.path("figures", "tca_corpus", "sectors_over_time.png"),
        width = 12,
        height = 12,
        figure
    )

    rm(figure_1, figure_all, figure)
}
Show the code
#|

if (length(list.files(file.path("figures", "tca_corpus"), pattern = "sectors_proportions_over_time")) < 2) {

    figure <- readRDS(file.path(file.path("data", "tca_corpus", "sectors_over_time.rds"))) |>
        dplyr::filter(
            publication_year >= 1950
        ) |>
        group_by(publication_year) |>
        mutate(count_all = count_all / sum(count_all)) |>
        ggplot() +
        geom_col(
            aes(
                x = publication_year,
                y = count_all,
                fill = sector
            ),
            position = "stack"
        ) +
        scale_x_continuous(breaks = seq(1900, 2020, 10)) +
        scale_y_continuous(
           "Proportion of Publications" # ,
        #    limits = c(0, 1.0001)
        ) +
        labs(
            title = "Publications clssified into Sectors over time. Each publication has up to three sectors assigned.",
            x = "Year",
            y = "Proportion"
        ) +
        theme_minimal() +
        theme(
            legend.position = "right"
        )

    # ggplot2::ggsave(
    #     file.path("figures", "tca_corpus", "sectors_proportions_over_time.pdf"),
    #     width = 12,
    #     height = 12,
    #     figure
    # )
    # ggplot2::ggsave(
    #     file.path("figures", "tca_corpus", "sectors_proportions_over_time.png"),
    #     width = 12,
    #     height = 12,
    #     figure
    # )

    rm(figure)
}

Results

Assessment of Search Terms Using OpenAlex

Number of Hits per Individual Corpus

Here we show the number of hits for the key papers in the different individual corpi. The columns represent the different search terms as defined in Section 2.1.

Show the code
dat <- cbind(
    search_term_hits
)

rownames(dat) <- dplyr::recode(
    rownames(dat),
    "transformative change" = "Transformative Change @sec-transform",
    "nature environment" = "Nature @sec-nature",
    "tca corpus" = "Assessment Corpus @sec-tca-corpus",
    "Chapter 1 01" = "Ch1 01 @sec-ch1-01",
    "Chapter 1 02" = "Ch1 02 @sec-ch1-02",
    "Chapter 1 03" = "Ch1 03 @sec-ch1-03",
    "Chapter 1 04" = "Ch1 04 @sec-ch1-04",
    "Chapter 1 05" = "Ch1 05 @sec-ch1-05",
    "Chapter 1 06" = "Ch1 06 @sec-ch1-06",
    "Chapter 2" = "Ch2  @sec-ch2",
    "Chapter 3 01" = "Ch3 01 @sec-ch3-01",
    "Chapter 3 02" = "Ch3 02 @sec-ch3-02",
    "Chapter 3 03" = "Ch3 03 @sec-ch3-03",
    "Chapter 3 04" = "Ch3 04 @sec-ch3-04",
    "Chapter 3 05" = "Ch3 05 @sec-ch3-05",
    "Chapter 3 06" = "Ch3 06 @sec-ch3-06",
    "Chapter 4 01" = "Ch4 01 @sec-ch4-01",
    "Chapter 4 02" = "Ch4 02 @sec-ch4-02",
    "Chapter 5 vision" = "Ch5 Vision @sec-ch5_vision",
    "Chapter 5 vision case" = "Ch5 Vision Case @sec-ch5_vision_case",
    "case" = "Ch5 Case @sec-case"
)

dat |>
    knitr::kable(
        caption = "Number of hits",
    )
Number of hits
count db_response_time_ms
oa 250,860,978 19
Transformative Change Section 2.1.1 18,637,717 3518
Nature Section 2.1.2 24,620,063 2915
Assessment Corpus Section 2.1.3 4,627,113 3726
Ch1 01 Section 2.1.4.1 627,674 194
Ch1 02 Section 2.1.4.2 3,234,873 275
Ch1 03 Section 2.1.4.3 16,164,129 439
Ch1 04 Section 2.1.4.4 2,513,933 377
Ch1 05 Section 2.1.4.5 25,981,255 801
Ch1 06 Section 2.1.4.6 6,511,922 615
Ch2 Section 2.1.5 109,798,896 5903
Ch3 01 Section 2.1.6.1 15,997,190 843
Ch3 02 Section 2.1.6.2 33,631,053 2038
Ch3 03 Section 2.1.6.3 28,870,432 1030
Ch3 04 Section 2.1.6.4 10,802,743 878
Ch3 05 Section 2.1.6.5 13,193,556 1048
Ch3 06 Section 2.1.6.6 20,866,069 1435
Ch4 01 Section 2.1.7.1 884,733 1427
Ch4 02 Section 2.1.7.2 21 1372
Ch5 Case Section 2.1.8.2 34,863,543 2024
Chapter 2 vision case 27,720,686 5417
Show the code
rm(dat)

Key papers in different Individual Corpi

Show the code
#|

tbl <- lapply(
    names(key_works_hits),
    function(n) {
        kwh <- key_works_hits[[n]]
        if (nrow(kwh) > 0) {
            total <- grepl("Total", rownames(kwh))
            rownames(kwh)[!total] <- paste0(n, " - <a href='https://doi.org/", rownames(kwh)[!total], "' target='_blank'>Click here</a>")
            rownames(kwh)[total] <- paste0("**", n, " - Total**")
            kwh |>
                arrange(Total) |>
                apply(
                    c(1, 2),
                    function(x) {
                        ifelse(x == 0, "<font color='red'>0</font>", paste0("<font color='green'>", x, "</font>"))
                    }
                ) |>
                as.data.frame()
        } else {
            return(NULL)
        }
    }
)
tbl <- tbl[sapply(tbl, class) != "NULL"]
tbl <- do.call(what = rbind, tbl)


detail <- rbind(
    "**overall**" = c(
        paste0(
            "**",
            search_term_hits |>
                select(count) |>
                unlist() |>
                as.vector(),
            "**"
        ),
        ""
    ),
    tbl
)

detail <- detail |>
    dplyr::rename(
        "Transformative Change @sec-transform" = s_1_transformative_change,
        "Nature @sec-nature" = s_1_nature_environment,
        "Assessment Corpus @sec-tca-corpus" = s_1_tca_corpus,
        "Ch1 01 @sec-ch1-01" = s_1_ch1_01,
        "Ch1 02 @sec-ch1-02" = s_1_ch1_02,
        "Ch1 03 @sec-ch1-03" = s_1_ch1_03,
        "Ch1 04 @sec-ch1-04" = s_1_ch1_04,
        "Ch1 05 @sec-ch1-05" = s_1_ch1_05,
        "Ch1 06 @sec-ch1-06" = s_1_ch1_06,
        "Ch2  @sec-ch2" = s_1_ch2,
        "Ch3 01 @sec-ch3-01" = s_1_ch3_01,
        "Ch3 02 @sec-ch3-02" = s_1_ch3_02,
        "Ch3 03 @sec-ch3-03" = s_1_ch3_03,
        "Ch3 04 @sec-ch3-04" = s_1_ch3_04,
        "Ch3 05 @sec-ch3-05" = s_1_ch3_05,
        "Ch3 06 @sec-ch3-06" = s_1_ch3_06,
        "Ch4 01 @sec-ch4-01" = s_1_ch4_01,
        "Ch4 02 @sec-ch4-02" = s_1_ch4_02,
        # "Ch5 Vision @sec-ch5_vision" = s_1_ch5_vision,
        "Ch5 Case @sec-case" = s_1_case,
        # "Ch5 Vision Case @sec-ch5_vision_case" = s_1_ch5_vision_case
    )

Key Papers in Individual Corpi

Summary

Each column is a different search term, and each row consists of the key papers of a specific chapter and the author who provided the key papers. The number is the number of key papers occurring in the Individual Corpus.

Show the code
in_summary <- grepl("Total|overall", rownames(detail))
knitr::kable(
    detail[in_summary, ]
)
s_1_oa Transformative Change Section 2.1.1 Nature Section 2.1.2 Assessment Corpus Section 2.1.3 Ch1 01 Section 2.1.4.1 Ch1 02 Section 2.1.4.2 Ch1 03 Section 2.1.4.3 Ch1 04 Section 2.1.4.4 Ch1 05 Section 2.1.4.5 Ch1 06 Section 2.1.4.6 Ch2 Section 2.1.5 Ch3 01 Section 2.1.6.1 Ch3 02 Section 2.1.6.2 Ch3 03 Section 2.1.6.3 Ch3 04 Section 2.1.6.4 Ch3 05 Section 2.1.6.5 Ch3 06 Section 2.1.6.6 Ch4 01 Section 2.1.7.1 Ch4 02 Section 2.1.7.2 Ch5 Case Section 2.1.8.2 s_1_ch2_vision_case Total
overall 250,860,978 18,637,717 24,620,063 4,627,113 627,674 3,234,873 16,164,129 2,513,933 25,981,255 6,511,922 109,798,896 15,997,190 33,631,053 28,870,432 10,802,743 13,193,556 20,866,069 884,733 21 34,863,543 27,720,686
Ch_1 - Total 42 40 41 39 19 28 35 30 31 30 41 30 33 33 22 33 35 28 0 35 35 659
Ch_2 - Total 22 20 22 20 9 17 18 12 17 18 22 20 19 19 15 21 21 16 0 18 18 363
Ch_3_Cl_3 - Total 4 4 4 4 3 3 4 3 4 4 4 4 4 4 4 4 4 3 0 4 4 75
Ch_3_Cl_4 - Total 5 5 5 5 5 4 5 5 5 5 5 5 5 5 5 5 5 4 0 5 5 97
Ch_3_Cl_5 - Total 3 2 3 2 0 2 2 2 2 2 2 2 2 2 2 2 2 2 0 2 2 39
Ch_3_Cl_6 - Total 6 6 5 5 1 1 2 3 1 3 5 2 4 5 1 1 5 2 0 3 3 63
Ch_3 - Total 4 4 4 4 2 1 2 2 3 3 4 3 4 3 1 2 3 2 0 4 4 58
Ch_4_Cl_1 - Total 7 4 7 4 1 4 5 5 3 5 7 4 4 4 4 6 7 4 0 4 4 92
Ch_4_Cl_2 - Total 4 3 3 3 2 2 3 1 2 2 3 2 3 3 1 3 3 2 0 2 2 48
Ch_4_Cl_3 - Total 5 5 5 5 2 2 4 2 3 3 4 3 4 4 3 3 4 2 0 4 4 70
Ch_4_Cl_4 - Total 4 2 4 2 1 1 3 1 1 2 4 2 1 2 2 2 4 1 0 3 3 44
Ch_4_Cl_5 - Total 5 3 4 3 1 2 4 2 4 2 5 5 4 4 3 3 5 3 0 4 4 69
Ch_5 - Total 35 33 33 31 20 23 27 27 26 25 35 29 30 33 26 28 30 20 0 27 27 564
all - Total 134 120 128 116 60 82 105 87 93 95 130 102 106 110 82 104 118 81 0 104 104 2060

Detail

Show the code
knitr::kable(
    detail
)
s_1_oa Transformative Change Section 2.1.1 Nature Section 2.1.2 Assessment Corpus Section 2.1.3 Ch1 01 Section 2.1.4.1 Ch1 02 Section 2.1.4.2 Ch1 03 Section 2.1.4.3 Ch1 04 Section 2.1.4.4 Ch1 05 Section 2.1.4.5 Ch1 06 Section 2.1.4.6 Ch2 Section 2.1.5 Ch3 01 Section 2.1.6.1 Ch3 02 Section 2.1.6.2 Ch3 03 Section 2.1.6.3 Ch3 04 Section 2.1.6.4 Ch3 05 Section 2.1.6.5 Ch3 06 Section 2.1.6.6 Ch4 01 Section 2.1.7.1 Ch4 02 Section 2.1.7.2 Ch5 Case Section 2.1.8.2 s_1_ch2_vision_case Total
overall 250,860,978 18,637,717 24,620,063 4,627,113 627,674 3,234,873 16,164,129 2,513,933 25,981,255 6,511,922 109,798,896 15,997,190 33,631,053 28,870,432 10,802,743 13,193,556 20,866,069 884,733 21 34,863,543 27,720,686
Ch_1 - Click here 1 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 3
Ch_1 - Click here 1 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 3
Ch_1 - Click here 1 1 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 4
Ch_1 - Click here 1 1 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0 0 0 1 1 6
Ch_1 - Click here 1 1 1 1 0 0 1 0 0 0 1 0 0 0 0 1 1 0 0 0 0 7
Ch_1 - Click here 1 1 1 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 1 1 7
Ch_1 - Click here 1 1 1 1 0 1 1 0 0 1 1 0 0 0 0 1 0 0 0 0 0 8
Ch_1 - Click here 1 1 1 1 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 1 8
Ch_1 - Click here 1 1 1 1 0 0 0 0 1 0 1 1 1 0 0 0 0 0 0 1 1 9
Ch_1 - Click here 1 1 1 1 0 0 0 0 0 1 1 0 1 1 0 0 1 0 0 1 1 10
Ch_1 - Click here 1 1 1 1 0 0 1 0 0 0 1 0 1 1 0 1 1 0 0 1 1 11
Ch_1 - Click here 1 1 1 1 0 1 1 0 0 1 1 0 0 1 0 1 1 1 0 0 0 11
Ch_1 - Click here 1 1 1 1 0 0 1 1 0 0 1 1 0 1 0 1 1 1 0 0 0 11
Ch_1 - Click here 1 1 1 1 0 1 1 1 0 0 1 1 1 1 1 1 1 0 0 1 1 15
Ch_1 - Click here 1 1 1 1 1 1 1 1 1 0 1 1 1 1 0 1 1 0 0 1 1 16
Ch_1 - Click here 1 1 1 1 0 1 0 1 1 1 1 1 1 1 0 1 1 1 0 1 1 16
Ch_1 - Click here 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 0 1 1 0 1 1 16
Ch_1 - Click here 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 1 1 0 0 1 1 16
Ch_1 - Click here 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 17
Ch_1 - Click here 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 17
Ch_1 - Click here 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 17
Ch_1 - Click here 1 1 1 1 0 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 17
Ch_1 - Click here 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 0 1 1 17
Ch_1 - Click here 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 17
Ch_1 - Click here 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 18
Ch_1 - Click here 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 18
Ch_1 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 18
Ch_1 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_1 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_1 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_1 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_1 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_1 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_1 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_1 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_1 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_1 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_1 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_1 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_1 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_1 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_1 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_1 - Total 42 40 41 39 19 28 35 30 31 30 41 30 33 33 22 33 35 28 0 35 35 659
Ch_2 - Click here 1 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 4
Ch_2 - Click here 1 1 1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 0 0 0 0 9
Ch_2 - Click here 1 0 1 0 0 0 0 0 1 0 1 1 0 0 0 1 1 1 0 1 1 9
Ch_2 - Click here 1 1 1 1 0 1 0 1 0 1 1 0 0 0 0 1 1 0 0 1 1 11
Ch_2 - Click here 1 1 1 1 0 1 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 12
Ch_2 - Click here 1 1 1 1 0 1 1 0 1 0 1 1 1 1 1 1 1 1 0 0 0 14
Ch_2 - Click here 1 1 1 1 0 1 0 0 1 1 1 1 1 1 1 1 1 0 0 1 1 15
Ch_2 - Click here 1 1 1 1 0 0 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 16
Ch_2 - Click here 1 1 1 1 0 1 1 0 1 1 1 1 1 1 0 1 1 1 0 1 1 16
Ch_2 - Click here 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 1 1 0 0 1 1 16
Ch_2 - Click here 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 17
Ch_2 - Click here 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 18
Ch_2 - Click here 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 1 1 18
Ch_2 - Click here 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 18
Ch_2 - Click here 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 18
Ch_2 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 18
Ch_2 - Click here 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 18
Ch_2 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_2 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_2 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_2 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_2 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_2 - Total 22 20 22 20 9 17 18 12 17 18 22 20 19 19 15 21 21 16 0 18 18 363
Ch_3_Cl_3 - Click here 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 17
Ch_3_Cl_3 - Click here 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 18
Ch_3_Cl_3 - Click here 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 18
Ch_3_Cl_3 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_3_Cl_3 - Total 4 4 4 4 3 3 4 3 4 4 4 4 4 4 4 4 4 3 0 4 4 75
Ch_3_Cl_4 - Click here 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 17
Ch_3_Cl_4 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_3_Cl_4 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_3_Cl_4 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_3_Cl_4 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_3_Cl_4 - Total 5 5 5 5 5 4 5 5 5 5 5 5 5 5 5 5 5 4 0 5 5 97
Ch_3_Cl_5 - Click here 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
Ch_3_Cl_5 - Click here 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 18
Ch_3_Cl_5 - Click here 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 18
Ch_3_Cl_5 - Total 3 2 3 2 0 2 2 2 2 2 2 2 2 2 2 2 2 2 0 2 2 39
Ch_3_Cl_6 - Click here 1 1 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 5
Ch_3_Cl_6 - Click here 1 1 0 0 0 0 0 0 0 0 1 1 1 1 0 0 1 0 0 0 0 6
Ch_3_Cl_6 - Click here 1 1 1 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 7
Ch_3_Cl_6 - Click here 1 1 1 1 0 0 0 1 0 1 1 0 0 0 0 0 1 0 0 1 1 9
Ch_3_Cl_6 - Click here 1 1 1 1 0 0 1 0 0 1 1 0 1 1 0 0 1 1 0 1 1 12
Ch_3_Cl_6 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_3_Cl_6 - Total 6 6 5 5 1 1 2 3 1 3 5 2 4 5 1 1 5 2 0 3 3 63
Ch_3 - Click here 1 1 1 1 0 0 0 0 1 0 1 1 1 0 0 0 0 0 0 1 1 9
Ch_3 - Click here 1 1 1 1 0 0 0 0 0 1 1 0 1 1 0 0 1 0 0 1 1 10
Ch_3 - Click here 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 18
Ch_3 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 18
Ch_3 - Total 4 4 4 4 2 1 2 2 3 3 4 3 4 3 1 2 3 2 0 4 4 58
Ch_4_Cl_1 - Click here 1 0 1 0 0 0 0 1 0 0 1 0 0 0 0 0 1 0 0 0 0 4
Ch_4_Cl_1 - Click here 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 4
Ch_4_Cl_1 - Click here 1 0 1 0 0 0 1 0 0 1 1 0 0 0 0 1 1 0 0 0 0 6
Ch_4_Cl_1 - Click here 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 18
Ch_4_Cl_1 - Click here 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 18
Ch_4_Cl_1 - Click here 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 18
Ch_4_Cl_1 - Click here 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 1 1 18
Ch_4_Cl_1 - Total 7 4 7 4 1 4 5 5 3 5 7 4 4 4 4 6 7 4 0 4 4 92
Ch_4_Cl_2 - Click here 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Ch_4_Cl_2 - Click here 1 1 1 1 0 0 1 0 0 0 1 0 1 1 0 1 1 0 0 0 0 9
Ch_4_Cl_2 - Click here 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 0 1 1 17
Ch_4_Cl_2 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_4_Cl_2 - Total 4 3 3 3 2 2 3 1 2 2 3 2 3 3 1 3 3 2 0 2 2 48
Ch_4_Cl_3 - Click here 1 1 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 5
Ch_4_Cl_3 - Click here 1 1 1 1 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 1 1 8
Ch_4_Cl_3 - Click here 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 1 1 0 0 1 1 16
Ch_4_Cl_3 - Click here 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 18
Ch_4_Cl_3 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_4_Cl_3 - Total 5 5 5 5 2 2 4 2 3 3 4 3 4 4 3 3 4 2 0 4 4 70
Ch_4_Cl_4 - Click here 1 0 1 0 0 0 1 1 0 0 1 0 0 0 0 0 1 0 0 0 0 5
Ch_4_Cl_4 - Click here 1 0 1 0 0 0 1 0 0 0 1 0 0 1 1 1 1 0 0 1 1 9
Ch_4_Cl_4 - Click here 1 1 1 1 0 1 0 0 0 1 1 1 0 0 0 0 1 0 0 1 1 10
Ch_4_Cl_4 - Click here 1 1 1 1 1 0 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 17
Ch_4_Cl_4 - Total 4 2 4 2 1 1 3 1 1 2 4 2 1 2 2 2 4 1 0 3 3 44
Ch_4_Cl_5 - Click here 1 0 1 0 0 0 0 0 0 0 1 1 1 1 0 0 1 0 0 0 0 6
Ch_4_Cl_5 - Click here 1 0 0 0 0 0 1 1 1 0 1 1 0 0 0 0 1 0 0 1 1 8
Ch_4_Cl_5 - Click here 1 1 1 1 0 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 17
Ch_4_Cl_5 - Click here 1 1 1 1 1 0 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 17
Ch_4_Cl_5 - Click here 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 17
Ch_4_Cl_5 - Total 5 3 4 3 1 2 4 2 4 2 5 5 4 4 3 3 5 3 0 4 4 69
Ch_5 - Click here 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 2
Ch_5 - Click here 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 1 5
Ch_5 - Click here 1 1 1 1 0 0 0 0 0 1 1 0 0 1 0 0 1 0 0 0 0 7
Ch_5 - Click here 1 1 1 1 0 0 1 0 0 0 1 1 1 1 0 0 0 0 0 0 0 8
Ch_5 - Click here 1 0 1 0 0 0 1 0 0 0 1 0 0 1 1 1 1 0 0 1 1 9
Ch_5 - Click here 1 1 0 0 0 1 1 0 1 1 1 0 0 1 0 0 0 0 0 1 1 9
Ch_5 - Click here 1 1 1 1 0 0 1 1 0 0 1 1 1 1 0 0 0 0 0 0 0 9
Ch_5 - Click here 1 1 1 1 0 0 0 1 0 0 1 0 1 1 1 1 1 0 0 0 0 10
Ch_5 - Click here 1 1 1 1 0 0 0 1 0 0 1 1 1 1 1 1 1 0 0 0 0 11
Ch_5 - Click here 1 1 1 1 0 0 0 1 0 0 1 1 1 1 1 1 1 0 0 0 0 11
Ch_5 - Click here 1 1 1 1 0 1 0 0 1 0 1 1 1 1 0 1 1 1 0 0 0 12
Ch_5 - Click here 1 1 1 1 0 1 0 1 1 0 1 1 1 1 1 1 1 0 0 1 1 15
Ch_5 - Click here 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 0 1 0 0 1 1 15
Ch_5 - Click here 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 17
Ch_5 - Click here 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 17
Ch_5 - Click here 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 18
Ch_5 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 18
Ch_5 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 18
Ch_5 - Click here 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 1 1 18
Ch_5 - Click here 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 18
Ch_5 - Click here 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 18
Ch_5 - Click here 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 18
Ch_5 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_5 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_5 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_5 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_5 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_5 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_5 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_5 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_5 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_5 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_5 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_5 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_5 - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
Ch_5 - Total 35 33 33 31 20 23 27 27 26 25 35 29 30 33 26 28 30 20 0 27 27 564
all - Click here 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
all - Click here 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
all - Click here 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 2
all - Click here 1 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 3
all - Click here 1 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 3
all - Click here 1 1 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 4
all - Click here 1 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 4
all - Click here 1 0 1 0 0 0 0 1 0 0 1 0 0 0 0 0 1 0 0 0 0 4
all - Click here 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 4
all - Click here 1 1 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 5
all - Click here 1 0 1 0 0 0 1 1 0 0 1 0 0 0 0 0 1 0 0 0 0 5
all - Click here 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 1 5
all - Click here 1 1 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0 0 0 1 1 6
all - Click here 1 1 0 0 0 0 0 0 0 0 1 1 1 1 0 0 1 0 0 0 0 6
all - Click here 1 0 1 0 0 0 1 0 0 1 1 0 0 0 0 1 1 0 0 0 0 6
all - Click here 1 0 1 0 0 0 0 0 0 0 1 1 1 1 0 0 1 0 0 0 0 6
all - Click here 1 1 1 1 0 0 1 0 0 0 1 0 0 0 0 1 1 0 0 0 0 7
all - Click here 1 1 1 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 1 1 7
all - Click here 1 1 1 1 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 7
all - Click here 1 1 1 1 0 0 0 0 0 1 1 0 0 1 0 0 1 0 0 0 0 7
all - Click here 1 1 1 1 0 1 1 0 0 1 1 0 0 0 0 1 0 0 0 0 0 8
all - Click here 1 1 1 1 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 1 8
all - Click here 1 1 1 1 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 1 1 8
all - Click here 1 0 0 0 0 0 1 1 1 0 1 1 0 0 0 0 1 0 0 1 1 8
all - Click here 1 1 1 1 0 0 1 0 0 0 1 1 1 1 0 0 0 0 0 0 0 8
all - Click here 1 1 1 1 0 0 0 0 1 0 1 1 1 0 0 0 0 0 0 1 1 9
all - Click here 1 1 1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 0 0 0 0 9
all - Click here 1 0 1 0 0 0 0 0 1 0 1 1 0 0 0 1 1 1 0 1 1 9
all - Click here 1 1 1 1 0 0 0 1 0 1 1 0 0 0 0 0 1 0 0 1 1 9
all - Click here 1 1 1 1 0 0 1 0 0 0 1 0 1 1 0 1 1 0 0 0 0 9
all - Click here 1 0 1 0 0 0 1 0 0 0 1 0 0 1 1 1 1 0 0 1 1 9
all - Click here 1 1 0 0 0 1 1 0 1 1 1 0 0 1 0 0 0 0 0 1 1 9
all - Click here 1 1 1 1 0 0 1 1 0 0 1 1 1 1 0 0 0 0 0 0 0 9
all - Click here 1 1 1 1 0 0 0 0 0 1 1 0 1 1 0 0 1 0 0 1 1 10
all - Click here 1 1 1 1 0 1 0 0 0 1 1 1 0 0 0 0 1 0 0 1 1 10
all - Click here 1 1 1 1 0 0 0 1 0 0 1 0 1 1 1 1 1 0 0 0 0 10
all - Click here 1 1 1 1 0 0 1 0 0 0 1 0 1 1 0 1 1 0 0 1 1 11
all - Click here 1 1 1 1 0 1 1 0 0 1 1 0 0 1 0 1 1 1 0 0 0 11
all - Click here 1 1 1 1 0 0 1 1 0 0 1 1 0 1 0 1 1 1 0 0 0 11
all - Click here 1 1 1 1 0 1 0 1 0 1 1 0 0 0 0 1 1 0 0 1 1 11
all - Click here 1 1 1 1 0 0 0 1 0 0 1 1 1 1 1 1 1 0 0 0 0 11
all - Click here 1 1 1 1 0 0 0 1 0 0 1 1 1 1 1 1 1 0 0 0 0 11
all - Click here 1 1 1 1 0 1 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 12
all - Click here 1 1 1 1 0 0 1 0 0 1 1 0 1 1 0 0 1 1 0 1 1 12
all - Click here 1 1 1 1 0 1 0 0 1 0 1 1 1 1 0 1 1 1 0 0 0 12
all - Click here 1 1 1 1 0 1 1 0 1 0 1 1 1 1 1 1 1 1 0 0 0 14
all - Click here 1 1 1 1 0 1 1 1 0 0 1 1 1 1 1 1 1 0 0 1 1 15
all - Click here 1 1 1 1 0 1 0 0 1 1 1 1 1 1 1 1 1 0 0 1 1 15
all - Click here 1 1 1 1 0 1 0 1 1 0 1 1 1 1 1 1 1 0 0 1 1 15
all - Click here 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 0 1 0 0 1 1 15
all - Click here 1 1 1 1 1 1 1 1 1 0 1 1 1 1 0 1 1 0 0 1 1 16
all - Click here 1 1 1 1 0 1 0 1 1 1 1 1 1 1 0 1 1 1 0 1 1 16
all - Click here 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 0 1 1 0 1 1 16
all - Click here 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 1 1 0 0 1 1 16
all - Click here 1 1 1 1 0 0 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 16
all - Click here 1 1 1 1 0 1 1 0 1 1 1 1 1 1 0 1 1 1 0 1 1 16
all - Click here 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 1 1 0 0 1 1 16
all - Click here 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 1 1 0 0 1 1 16
all - Click here 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 17
all - Click here 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 17
all - Click here 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 17
all - Click here 1 1 1 1 0 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 17
all - Click here 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 0 1 1 17
all - Click here 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 17
all - Click here 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 17
all - Click here 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 17
all - Click here 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 0 1 1 17
all - Click here 1 1 1 1 1 0 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 17
all - Click here 1 1 1 1 0 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 17
all - Click here 1 1 1 1 1 0 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 17
all - Click here 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 17
all - Click here 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 17
all - Click here 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 17
all - Click here 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 18
all - Click here 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 18
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 18
all - Click here 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 18
all - Click here 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 1 1 18
all - Click here 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 18
all - Click here 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 18
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 18
all - Click here 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 18
all - Click here 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 18
all - Click here 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 18
all - Click here 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 18
all - Click here 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 18
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 18
all - Click here 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 18
all - Click here 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 18
all - Click here 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 18
all - Click here 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 1 1 18
all - Click here 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 18
all - Click here 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 18
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 18
all - Click here 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 1 1 18
all - Click here 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 18
all - Click here 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 18
all - Click here 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 18
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Click here 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 19
all - Total 134 120 128 116 60 82 105 87 93 95 130 102 106 110 82 104 118 81 0 104 104 2060

TCA Corpus properties

Publications over time

The red line is the cumulative proportion of publications, the blue line the cumulative proportion of all of the Op[enAlex corpus. Both use the secondeary (red) axis.

To download high resolution, click here

Show the code
readRDS(file.path(".", "data", "tca_corpus", "publications_over_time_tca_corpus.rds")) |> 
    IPBES.R::table_dt(fn = "publications_over_time")

Countries in TCA Corpus

The countries are based on the countries of the institutes of all authors, weighted by 1/no_ authors_per_paper.

The following calculations were done:

  • **count** =ifelse(is.na(count), 0, count)`
  • **log_count** =log(count + 1)`
  • **p** =count / sum(count)`
  • **count_oa** =ifelse(is.na(count_oa), 0, count)`
  • **log_count_oa** =log(count_oa + 1)`
  • **p_oa** =count_oa / sum(count_oa)`
  • **p_diff** =(p_oa - p) * 100`
  • **p_ratio** =count / count_oa`
Show the code
readRDS(file.path(".", "data", "tca_corpus", "countries_tca_corpus.rds")) |>
    IPBES.R::table_dt(fn = "publications_per_country")

All Years

To download high resolution, click here

Sectors over time

For clarity, the log of the cumulative sum of the sectors over time are shown here.

The top graph shows only the primary sector assigned, the bottom graph all sectors (first, secondary and tertiary)

To download high resolution, click here

Show the code
readRDS(file.path(".", "data", "tca_corpus", "sectors_over_time.rds")) |>
    IPBES.R::table_dt(
        fn = "sectors_over_time",
        fixedColumns = list(leftColumns = 3)
    )

Topics in corpus

Show the code
#|

cs <- cumsum(prim_topics_tca_corpus$count)
cs |>
    plot(
        type = "l",
        xlab = "Topic",
        ylab = "Cumulative Count",
        main = "Cumulative Topics in TCA Corpus"
    )

abline(
    h = 0.95 * cs[length(cs)],
    v = min(which(cs > 0.95 * cs[length(cs)])),
    col = "red"
)

text(
    x = 0.5 * length(cs),
    y = 0.95 * cs[length(cs)],
    pos = 3,
    labels = "95% of the corpus",
    col = "red"
)

Show the code
#|

prim_topics_tca_corpus |>
    relocate(count, .after = "id") |>
    IPBES.R::table_dt(
        fn = "topics_tca_corpus", 
    )    
Warning in instance$preRenderHook(instance): It seems your data is too big for
client-side DataTables. You may consider server-side processing:
https://rstudio.github.io/DT/server.html

SubFields in Corpus

Show the code
#|
cs <- prim_topics_tca_corpus |>
    mutate(
        id = NULL,
        topic_name = NULL,
        keywords = NULL,
        summary = NULL,
        wikipedia_url = NULL
    ) |>
    group_by(
        subfield_id,
    ) |>
    summarise(
        count = sum(count)
    ) |>
    arrange(desc(count)) |>
    dplyr::select(count) |>
    unlist() |>
    cumsum()
cs |>
    plot(
        type = "l",
        xlab = "Subfield",
        ylab = "Cumulative Count",
        main = "Cumulative Subfields in TCA Corpus"
    )

abline(
    h = 0.95 * cs[length(cs)],
    v = min(which(cs > 0.95 * cs[length(cs)])),
    col = "red"
)

text(
    x = 0.5 * length(cs),
    y = 0.95 * cs[length(cs)],
    pos = 3,
    labels = "95% of the corpus",
    col = "red"
)

Show the code
#|

prim_topics_tca_corpus |>
    mutate(
        topic_id = NULL,
        topic_name = NULL,
        keywords = NULL,
        summary = NULL,
        wikipedia_url = NULL
    ) |>
    group_by(
        subfield_id,
        subfield_name,
        field_id,
        field_name,
        domain_id,
        domain_name
    ) |>
    summarise(
        count = sum(count),
        .groups = "drop"        
    ) |>
    arrange(desc(count)) |>
    relocate(count, .after = "subfield_id") |>
    DT::datatable(
        extensions = c(
            "Buttons",
            "FixedColumns",
            "Scroller"
        ),
        options = list(
            dom = "Bfrtip",
            buttons = list(
                list(
                    extend = "csv",
                    filename = fn
                ),
                list(
                    extend = "excel",
                    filename = fn
                ),
                list(
                    extend = "pdf",
                    filename = fn,
                    orientation = "landscape",
                    customize = DT::JS(
                        "function(doc) {",
                        "  doc.defaultStyle.fontSize = 5;", # Change the font size
                        "}"
                    )
                ),
                "print"
            ),
            scroller = TRUE,
            scrollY = JS("window.innerHeight * 0.7 + 'px'"),
            scrollX = TRUE,
            fixedColumns = list(leftColumns = 4)
        ),
        escape = FALSE
    )
  • TODO: Histogram / table with topics identified to identify non-relevant papers

Reuse

Citation

BibTeX citation:
@report{krug2024,
  author = {Krug, Rainer M.},
  title = {Data {Management} {Report} {Transformative} {Change}
    {Assessment} {Corpus} - {SOD}},
  date = {2024-04-09},
  doi = {10.5281/zenodo.10251349},
  langid = {en},
  abstract = {The literature search for the assessment corpus was
    conducted using search terms provided by the experts and refined in
    co-operation with the Knowldge and Data task force. The search was
    conducted using {[}OpenAlex{]}(https://openalex.org), scripted from
    {[}R{]}(https://cran.r-project.org) to use the
    {[}API{]}(https://docs.openalex.org). Search terms for the following
    searches were defined: **Transformative Change**, **Nature /
    Environment** and **additional search terms for individual chapters
    and sub-chapters** To assess the quality of the corpus, sets of
    key-papers were selected by the experts to verify if these are in
    the corpus. These key-papers were selected per chapter / sub-chapter
    to ensure that the corpus is representative of each chapter.}
}
For attribution, please cite this work as:
Krug, Rainer M. 2024. “Data Management Report Transformative Change Assessment Corpus - SOD.” Report Transformative Change Assessment Corpus. https://doi.org/10.5281/zenodo.10251349.